package com.itbac.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 自定义全局过滤器
 * 作用：统一鉴权
 * http://127.0.0.1/service-product/product/getById/1?token=admin
 *
 * 怎么防止跨过网关gateway直接访问微服务???
 *
 * 1.K8S：在使用Kubernetes部署SpringCloud架构时我们给网关的Service配置NodePort，
 * 其他后端服务的Service使用ClusterIp，这样在集群外就只能访问到网关了。
 *
 * 2.网络隔离：后端普通服务都部署在内网，通过防火墙策略限制只允许网关应用访问后端服务。
 *
 * 3.应用层拦截:请求后端服务时通过拦截器校验请求是否来自网关，如果不来自网关则提示不允许访问。
 */
@Component
@Slf4j
public class AuthGlobalFilter implements GlobalFilter,Ordered{
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //getQueryParams  获取请求参数中的token
        //getHeaders  获取请求头中的token
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        if (!"admin".equals(token)){
            log.info("认证失败了...");
            //设置状态码：401
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            //响应
            return exchange.getResponse().setComplete();
        }
        //放行,传递到下一个过滤器
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        //顺序，值越小越优先
        return 0;
    }
}
